﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Web.Mvc;
using Inovout.Data.Domain;

namespace Inovout.Web.Mvc
{
    /// <summary>
    /// 查询条件规则生成器
    /// </summary>
    /// <typeparam name="TModel"></typeparam>
    public class QueryCriteriaBuilder<TModel>
    {
        public QueryCriteriaBuilder(QueryCriteria queryCriteria = null)
        {
            queryCriteria = queryCriteria ?? new QueryCriteria();
            this.FilterCollectionBuilder = new FilterCriteriaColllectionBuilder<TModel>(queryCriteria.Filters);
            this.OrderCollectionBuilder = new OrderCriteriaColllectionBuilder<TModel>(queryCriteria.Orders);
        }
        /// <summary>
        /// 查询规则对象实例
        /// </summary>
        public QueryCriteria QueryCriteria { get { return new QueryCriteria(FilterCollectionBuilder, OrderCollectionBuilder); } }
        protected FilterCriteriaColllectionBuilder<TModel> FilterCollectionBuilder { get; private set; }
        protected OrderCriteriaColllectionBuilder<TModel> OrderCollectionBuilder { get; private set; }

        /// <summary>
        /// 增加一个老婆婆条件
        /// </summary>
        /// <typeparam name="TProperty">属性类型</typeparam>
        /// <param name="filterPropertyNameExpression">过滤的属性访问表达式</param>
        /// <param name="filterValue">过滤条件值</param>
        /// <returns>QueryCriteriaBuilder对象实例</returns>
        public QueryCriteriaBuilder<TModel> FilterFor<TProperty>(Expression<Func<TModel, TProperty>> filterPropertyNameExpression, dynamic filterValue = null)
        {
            return this.FilterFor(filterPropertyNameExpression, FilterOperation.Eq, filterValue);
        }
        /// <summary>
        /// 增加一个老婆婆条件
        /// </summary>
        /// <typeparam name="TProperty">属性类型</typeparam>
        /// <param name="filterPropertyNameExpression">过滤的属性访问表达式</param>
        /// <param name="filterOperation">过滤条件比较值</param>
        /// <param name="filterValue">过滤条件值</param>
        /// <returns></returns>
        public QueryCriteriaBuilder<TModel> FilterFor<TProperty>(Expression<Func<TModel, TProperty>> filterPropertyNameExpression,
            FilterOperation filterOperation, dynamic filterValue = null)
        {
            this.FilterCollectionBuilder.FilterFor(filterPropertyNameExpression, filterOperation, filterValue);
            return this;
        }
        /// <summary>
        /// 增加一个排序规则
        /// </summary>
        /// <typeparam name="TProperty">属性类型</typeparam>
        /// <param name="orderPropertyNameExpression">排序的属性访问器表达式</param>
        /// <param name="ascending">是否正序</param>
        /// <returns>QueryCriteriaBuilder对象实例</returns>
        public QueryCriteriaBuilder<TModel> OrderFor<TProperty>(Expression<Func<TModel, TProperty>> orderPropertyNameExpression, bool ascending = true)
        {
            this.OrderCollectionBuilder.OrderFor(orderPropertyNameExpression, ascending);
            return this;
        }
        /// <summary>
        /// 增加一个倒序排序规则
        /// </summary>
        /// <typeparam name="TProperty">属性类型</typeparam>
        /// <param name="orderPropertyNameExpression">排序的属性访问器表达式</param>
        /// <returns>QueryCriteriaBuilder对象实例</returns>
        public QueryCriteriaBuilder<TModel> OrderDescendingFor<TProperty>(Expression<Func<TModel, TProperty>> orderPropertyNameExpression)
        {
            return OrderFor(orderPropertyNameExpression, false);
        }
        /// <summary>
        /// 合并查询规则
        /// </summary>
        /// <param name="queryCriteria">查询规则对象实例</param>
        /// <returns>QueryCriteriaBuilder对象实例</returns>
        public QueryCriteriaBuilder<TModel> Merge(QueryCriteria queryCriteria)
        {
            if (queryCriteria != null)
            {
                this.Merge(queryCriteria.Filters);
                this.Merge(queryCriteria.Orders);
            }
            return this;
        }
        /// <summary>
        /// 合并排序规则
        /// </summary>
        /// <param name="orders">排序规则的集合</param>
        /// <returns>QueryCriteriaBuilder对象实例</returns>
        public QueryCriteriaBuilder<TModel> Merge(IEnumerable<OrderCriteria> orders)
        {
            this.OrderCollectionBuilder.Merge(orders);
            return this;

        }
        /// <summary>
        /// 合并过滤规则
        /// </summary>
        /// <param name="filters">过滤规则的集合</param>
        /// <returns>QueryCriteriaBuilder对象实例</returns>
        public QueryCriteriaBuilder<TModel> Merge(IEnumerable<FilterCriteria> filters)
        {
            this.FilterCollectionBuilder.Merge(filters);
            return this;
        }
    }

}
